package myJs.member.produceQrCode

import argonaut.Argonaut._
import myJs.CpLayer
import myJs.Implicits._
import myJs.cps.BootstrapTableCp.Column
import myJs.cps._
import myJs.myPkg.{FileSaver, GenerateOptions, JSZip, JSZipOptions, MyFetch, Qrcode, QrcodeOptions, SwalOptions, layer, swal}
import myJs.tool.Pojo._
import myJs.tool.Tool
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js
import scala.scalajs.js.JSON
import myJs.myPkg.jquery._
import org.scalajs.dom
import org.scalajs.dom.{HTMLImageElement, html}
import org.scalajs.dom.html.Canvas
import slinky.core.facade.React

import scala.scalajs.js.JSConverters._

/**
 * Created by yz on 21/1/2022
 */
@react object Cp {

  type Props = Unit

  type Ctx2D = dom.CanvasRenderingContext2D

  val curPage = ProduceQrcode

  val component = FunctionalComponent[Props] { props =>

    val (ids, setIds) = useState(List.empty[String])
    val (num, setNum) = useState("5")

    val formRef = React.createRef[html.Form]

    object FTool {

      def refreshQrcode = () => {
        val formJq = $(formRef.current)
        val bv = formJq.bv
        bv.validate()
        val valid = bv.isValid()
        if (valid) {
          val index = layer.alert(Tool.myElement, Tool.layerOptions)
          val url = "http://localhost:9000/panda/sampleId/getNewIds"
          val formData = formJq.serialize()
          MyFetch.post(url = s"${url}", data = formData, headers = Map("Content-Type" -> "application/x-www-form-urlencoded"),
          ).map { any =>
            val newIds = any.toJArS
            refreshCanvas(newIds)
            layer.close(index)
          }
        }
        $("#result").show()
        ()
      }

      def refreshCanvas(newIds: JArS) = {
        setIds(newIds.toList)
        val width = 200
        val height = 200
        val options = QrcodeOptions(errorCorrectionLevel = "H", width = 200)
        newIds.zipWithIndex.foreach { case (text, curI) =>
          val textInfo = js.Dictionary(
            "id" -> text,
            "soft" -> "panda"
          )
          Qrcode.toDataURL(JSON.stringify(textInfo), options, (error: js.UndefOr[String], url: String) => {
            val boxJq = $(s"#qrcodeBox${curI}")
            val imgJq = boxJq.find(s"img")
            val imgE = imgJq(0).asInstanceOf[HTMLImageElement]
            imgE.src = url
            val canvas = boxJq.find("canvas")(0).asInstanceOf[Canvas]
            canvas.width = width
            canvas.height = height
            val ctx = canvas.getContext("2d").asInstanceOf[Ctx2D]
            var textHasPlot = false
            imgE.onload = (e) => {
              if (!textHasPlot) {
                ctx.drawImage(imgE, 0, 0, width, height)
                val fontSize = 16
                ctx.font = s"bold ${fontSize}px Arial"
                val plotText = s"PN:${text}"
                val tw = ctx.measureText(plotText).width
                val ftop = height - fontSize
                val fleft = (width - tw) / 2
                ctx.textBaseline = "top"
                ctx.fillStyle = "#333"
                ctx.fillText(plotText, fleft, ftop)
                imgE.src = canvas.toDataURL(`type` = "image/png")
                textHasPlot = true
              }
            }
          })
        }
      }

      def downloadQrcode = () => {
        val zip = new JSZip()
        val es = $(".qrcodeBox img").es
        val ids = es.map { y =>
          $(y).dataValue
        }
        es.foreach { y =>
          val id = $(y).dataValue
          val fileName = s"${id}.png"
          val imageData = $(y).attr("src").get.
            replaceAll("^data:image/png;base64,", "")
          zip.file(fileName, imageData, JSZipOptions(base64 = true))
        }

        add2Db.foreach { x =>
          zip.generateAsync(GenerateOptions(`type` = "blob")).toFuture.foreach { content =>
            FileSaver.saveAs(content, s"qrcode_${es.size}.zip")
          }
        }
      }

      def add2Db = {
        println(Tool.getAccount)
        val dict = js.Dictionary(
          "ids" -> ids.toJSArray,
          "account"->Tool.getAccount
        )
        val url = "http://localhost:9000/panda/sampleId/add2Db"
        MyFetch.post(url = s"${url}", data = JSON.stringify(dict), headers = Map("Content-Type" -> "application/json"),
        ).map {
          xhr =>
        }
      }

      def numChange = (v: String) => {
        setNum(v)
      }

      def bootstrapValidator = {
        val formJq = $(formRef.current)
        val dict: js.Dictionary[js.Any] = js.Dictionary(
          "feedbackIcons" -> js.Dictionary(
            "valid" -> "glyphicon glyphicon-ok",
            "invalid" -> "glyphicon glyphicon-remove",
            "validating" -> "glyphicon glyphicon-refresh",
          ),
          "fields" -> js.Dictionary(
            "num" -> {
              val info = "数量"
              js.Dictionary(
                "validators" -> js.Dictionary(
                  "notEmpty" -> js.Dictionary(
                    "message" -> s"${info}不能为空!"
                  ),
                  "integer" -> js.Dictionary(
                    "message" -> s"${info}必须为整数",
                  ),
                  "between" -> js.Dictionary(
                    "min" -> 1,
                    "max" -> 50,
                    "message" -> s"${info}必须大于0小于50",
                  ),
                )
              )

            },
          )
        )
        formJq.bootstrapValidator(dict)
      }

    }

    useEffect(() => {
      FTool.bootstrapValidator
    }, List()
    )

    CpLayer(title = curPage.titleStr)(
      div(className := "page-content",
        div(className := "row-fluid",
          div(className := "row",
            div(className := "col-md-12 col-sm-12",
              div(className := "portlet light",
                div(className := "portlet-title",
                  div(className := "caption", s"${curPage.titleStr}")
                ),
                div(className := "portlet-body",

                  form(className := "form-horizontal", ref := formRef,
                    div(className := "form-group",
                      label(className := "control-label col-sm-2", "数量:"),
                      div(className := "col-sm-4",
                        PureInputCp(name = "num", value = num, onChange = FTool.numChange)
                      )
                    ),

                    div(className := "form-group",
                      div(className := "actions col-sm-offset-2 col-sm-2",
                        button(`type` := "button", className := "btn btn-primary", onClick := FTool.refreshQrcode,
                          i(className := "fa fa-plus"),
                          s" 生成二维码",
                        ),
                      )
                    ),

                  ),

                  div(id := "result", style := Style(display = Display.none),
                    hr(),
                    div(id := "download", style := Style(marginTop = "20px"),
                      button(className := "btn btn-primary", data - "value" := "ko_dodge.png",
                        onClick := FTool.downloadQrcode,
                        style := Style(marginLeft = "15px"),
                        i(className := "fa fa-download"),
                        s" 下载二维码",
                      )
                    ),
                    div(id := "qrcodeResult", style := Style(display = Display.flex, flexWrap = FlexWrap.wrap,
                      justifyContent = JustifyContent.left),

                      ids.zipWithIndex.map { case (idStr, curI) =>
                        div(key := s"${idStr}", className := "qrcodeBox", id := s"qrcodeBox${curI}",
                          style := Style(width = 200, height = 200, flex = 0),
                          img(className := "qrcodeImg", style := Style(display = Display.none), data - "value" := s"${idStr}"),
                          canvas(className := "canvas")
                        )
                      }

                    )
                  )

                ),
              )
            )
          )
        )
      )
    )

  }


}
